package net.stogi.dsper.ui.client.module.tag;

import java.util.ArrayList;
import java.util.List;

import net.stogi.common.gwt.dispatch.client.core.ActionManager;
import net.stogi.common.gwt.frame.client.core.EventBus;
import net.stogi.common.gwt.frame.client.mvp.AbstractPresenter;
import net.stogi.common.mvp.core.behavior.Behavior;
import net.stogi.dsper.api.dto.TagDto;
import net.stogi.dsper.ui.shared.module.tag.ListTagsAction;
import net.stogi.dsper.ui.shared.module.tag.ListTagsResult;
import net.stogi.dsper.ui.shared.module.tag.SaveTagsAction;
import net.stogi.dsper.ui.shared.module.tag.SaveTagsResult;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

class TagEditorPresenter extends AbstractPresenter {

	private TagEditorView tagEditorView;

	private List<TagDto> tagListModel;

	public TagEditorPresenter(TagEditorView tagEditorView, ActionManager actionManager, EventBus eventBus) {
		super(actionManager, eventBus);
		this.tagEditorView = tagEditorView;
		initBehavior();
		initHandlers();
	}

	@Override
	protected void initBehavior() {
		tagEditorView.setAddBehavior(new Behavior() {

			@Override
			public void behave() {
				tagEditorView.addTag();
			}
		});
		tagEditorView.setCancelBehavior(new Behavior() {

			@Override
			public void behave() {
				tagEditorView.disappear();
				eventBus.fireEvent(new TagEditorClosedEvent());
			}
		});
		tagEditorView.setSaveBehavior(new Behavior() {

			@Override
			public void behave() {
				List<String> tagList = tagEditorView.collectTags();
				if (tagList.size() > 0) {
					tagEditorView.block();
					executeSaveTags(tagList);
				}
				else {
					tagEditorView.disappear();
					eventBus.fireEvent(new TagEditorClosedEvent());
				}
			}
		});
	}

	@Override
	protected void initHandlers() {
		eventBus.addHandler(OpenTagEditorEvent.TYPE, new OpenTagEditorHandler() {

			@Override
			public void onOpenTagEditor(OpenTagEditorEvent event) {
				executeListTags();
				tagEditorView.appear();
			}
		});
	}

	private void executeListTags() {
		actionManager.execute(new ListTagsAction(), new AsyncCallback<ListTagsResult>() {

			@Override
			public void onFailure(Throwable caught) {
				internalHandleException(caught);
			}

			@Override
			public void onSuccess(ListTagsResult result) {
				tagListModel = result.getTagList();

				List<String> tagList = new ArrayList<String>();
				for (TagDto tag : tagListModel) {
					tagList.add(tag.getValue());
				}

				tagEditorView.displayTags(tagList);
				tagEditorView.unblock();
			}
		});
	}

	private void executeSaveTags(List<String> tagList) {
		actionManager.execute(new SaveTagsAction(tagList), new AsyncCallback<SaveTagsResult>() {

			@Override
			public void onFailure(Throwable caught) {
				internalHandleException(caught);
				tagEditorView.unblock();
			}

			@Override
			public void onSuccess(SaveTagsResult result) {
				tagEditorView.disappear();
				eventBus.fireEvent(new TagEditorClosedEvent());
			}
		});
	}

	private void internalHandleException(Throwable caught) {
		// TODO: Add some nice message module in order to show messages from
		// exceptions to user.
		GWT.log("execute*: fail", null);
	}
}
